package com.yex.service.otc.impl;

import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yex.base.WalletOper;
import com.yex.base.WalletOperEnum;
import com.yex.base.ZeroResultException;
import com.yex.dao.otc.OtcAppealDao;
import com.yex.dao.otc.OtcCoinDao;
import com.yex.dao.otc.OtcEntrustDao;
import com.yex.dao.otc.OtcOrderDao;
import com.yex.entity.UserEntity;
import com.yex.entity.WalletEntity;
import com.yex.entity.otc.*;
import com.yex.service.SysConfigService;
import com.yex.service.UserService;
import com.yex.service.WalletService;
import com.yex.service.otc.*;
import com.yex.utils.JsonResultVo;
import com.yex.utils.MathUtil;
import com.yex.utils.OrderUtils;
import com.yex.utils.Utils;
import com.yex.utils.vo.OtcAppealOperEnum;
import com.yex.utils.vo.OtcAppealVo;
import com.yex.utils.vo.OtcOperEnum;
import com.yex.utils.vo.RespInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.*;

import static com.yex.utils.MathUtil.mul;

/**
 * <p>
 * otc 订单表 服务实现类
 * </p>
 *
 * @author Little Liu
 * @since 2018-05-03
 */
@Service
public class OtcOrderServiceImpl extends ServiceImpl<OtcOrderDao, OtcOrder> implements IOtcOrderService {
    @Autowired
    private OtcOrderDao otcOrderMapper;
    @Autowired
    private OtcEntrustDao otcEntrustMapper;
    @Autowired
    private UserService fuserMapper;
    @Autowired
    private SysConfigService fsystemargsMapper;
    @Autowired
    private OtcCoinDao otcCoinMapper;
    @Autowired
    private WalletService otcWalletService;
    @Autowired
    private OtcAppealDao otcAppealMapper;

    @Autowired
    private IOtcAppealService otcAppealService;

    @Autowired
    private IOtcEntrustService otcEntrustService;
    @Autowired
    private SysConfigService fsystemargsService;



    @Autowired
    private IOtcCoinService otcCoinService;
    @Autowired
    private IOtcDayAmountService otcDayAmountService;
    @Autowired
    private IOtcFeeConfigService otcFeeConfigService;

    /**
     * 修改订单状态，判断订单信息是否与当前用户匹配，并且是否有权限修改相应状态，避免跨用户操作,跨角色操作
     * 参数：订单id，修改状态，用户实体
     * 返回：0失败，1成功，2非法操作
     */
    @Override
    public JsonResultVo nowUserOrderUpdate(Integer id, Integer status, Integer userId) {
        UserEntity fuser = fuserMapper.selectById(userId); //获取当前用户信息
        List buy = Arrays.asList(new Integer[]{0, 3, 5, -1});    //买家可操作的订单状态 0未完成 3已支付 5买家取消,-1上传凭证（不用更新数据）
        List sell = Arrays.asList(new Integer[]{1, 2}); //卖家可操做的订单状态 1已完成 2冻结
        List service = Arrays.asList(new Integer[]{6, 7});//客服可以操作 6仲裁凭证无效 7仲裁买家凭证有效
        //不同状态发送短信的匹配集合
        Map<Integer, String> mssageMap = new HashMap<>();
        //短信
        mssageMap.put(3, "seller_already_paid");//买家已支付，还有xx分钟超时自动放币
        mssageMap.put(1, "buyer_confirmation");//卖家确认收款放币
        mssageMap.put(2, "buyer_appeal");//卖家申诉
        mssageMap.put(5, "seller_cancel_order");//订单转至已取消订单类别（买家取消）
        mssageMap.put(-1, "seller_view_voucher&&buyer_upload_voucher");//对方已上传支付凭证，查看支付凭证
        String BuyOrSell;  //买方还是卖方
        String InvoiceOrReceipt; //委托方还是接单方
        OtcOrder otcOrder = otcOrderMapper.selectById(id); //根据订单id查询订单
        OtcEntrust otcEntrust = otcEntrustMapper.selectById(otcOrder.getEntrustId());  //根据委托id查询，委托信息
        //判断当前用户是委托方还是接单方
        if (otcOrder != null && otcOrder.getUserId() == fuser.getId()) {  //是委托方
            InvoiceOrReceipt = "Invoice";
        } else if (otcOrder != null && fuser.getId() == otcEntrust.getUserId()) {  //是接单方
            InvoiceOrReceipt = "Receipt";
        } else {  //什么都不是
            return new JsonResultVo(true, "非法操作", -1);
        }
        if (otcOrder.getType() == 0) { //判断委托类型 0买入 1卖出
            BuyOrSell = "Buy";
        } else {
            BuyOrSell = "Sell";
        }
        UserEntity wef_user = fuserMapper.selectById(otcEntrust.getUserId());//委托人信息
        OtcCoin otcCoin = otcCoinMapper.selectById(otcEntrust.getCoinId());//货币信息
        //判断操作的状态是买方还是卖方
        if (buy.contains(status)) { //是买方
            if (InvoiceOrReceipt.equals("Invoice") && BuyOrSell.equals("Buy")) { //用户是委托方并且委托类型是买入-->用户是买家
            } else if (InvoiceOrReceipt.equals("Receipt") && BuyOrSell.equals("Sell")) {//用户是接单方并且委托类型是卖出-->用户是买家
            } else {
                return new JsonResultVo(true, "非法操作", -2);
            }
        } else if (buy.contains(status)) {//是卖方
            if (InvoiceOrReceipt.equals("Receipt") && BuyOrSell.equals("Buy")) { //用户是接单方并且委托类型是买入-->用户是卖家
            } else if (InvoiceOrReceipt.equals("Invoice") && BuyOrSell.equals("Sell")) {//用户是委托方并且委托类型是卖出-->用户是卖家
            } else {
                return new JsonResultVo(true, "非法操作", -3);
            }
        } else {
            return new JsonResultVo(true, "非法操作", -4);
        }
        if (status != -1) {
            otcOrder.setStatus(status);
            //更新修改时间
            otcOrder.setModifyDate(new Date());
            Map<String, Object> map = new HashMap<>();
            map.put("status", status);
            map.put("id", otcOrder.getId());
            map.put("modifyDate", Utils.dateFormat(new Timestamp((new Date()).getTime())));
            map.put("nostatus", "and status != 4 and status!=5 and status!=6");//不等于取消状态
            if (otcOrderMapper.updateOrderStatus(map) == 0) {
                return new JsonResultVo(false, "操作失败：服务器异常或重复操作", -5);
            } else {
                //发送短信通知
                String[] codes = mssageMap.get(status).split("&&");
                Map<String, Object> parms = new HashMap<>();
                if (otcOrder.getType() == 1) {
                    otcOrder.setCountNum(MathUtil.sub(otcOrder.getCountNum(), otcOrder.getFees()));
                    otcOrder.setAmount(mul(otcOrder.getCountNum(), otcOrder.getPrize()));
                }
//                for (String code : codes) {
//                    parms.put("fKey", code);
//                    String content = fsystemargsMapper.selectByMap(parms).get(0).toString();
//                    content = content.replace("{coin_type}", otcCoin.getCoinName())
//                            .replace("{trading_time}", Utils.dateFormat(new Timestamp((new Date()).getTime())))
//                            .replace("{price}", otcOrder.getPrize() + "")
//                            .replace("{total_price}", otcOrder.getAmount() + "")
//                            .replace("{order_number}", otcOrder.getCountNum() + "")
//                            .replace("{contact_time}",redisService.getConfig("contact_time").toString());//真正的短信内容
//                    if (code.contains("buyer")) {
//                        userSupport.SendOtcMessage(fuser, content, 0); //发送短信通知给买家
//                    } else {
//                        userSupport.SendOtcMessage(wef_user, content, 0); //发送短信通知给卖家
//                    }
//                }
                return new JsonResultVo(true, "操作成功", 0);
            }

        } else {
            return new JsonResultVo(true, "允许上传", -1);
        }
    }


    /**
     * 修改订单状态，判断订单信息是否与当前用户匹配，并且是否有权限修改相应状态，避免跨用户操作,跨角色操作
     * 参数：订单id，修改状态，用户实体
     * 返回：0失败，1成功，2非法操作
     */
    @Override
    @Transactional
    public JsonResultVo updateOrder(Integer id, Integer type, Integer userId, Integer payMethod, boolean isService) {

        OtcOrder otcOrder = otcOrderMapper.selectById(id); //根据订单id查询订单
        OtcEntrust otcEntrust = otcEntrustMapper.selectById(otcOrder.getEntrustId());  //根据委托id查询，委托信息
        Date nowDate = new Date();
        //不同状态发送短信的匹配集合
        OtcOrder updateOrder = new OtcOrder();
        updateOrder.setId(otcOrder.getId());
        updateOrder.setModifyDate(nowDate);
        updateOrder.setStatus(type);
        updateOrder.setModifyDate(nowDate);
        int result = -1;
        String content = "";
        UserEntity entrustUser = fuserMapper.selectById(otcEntrust.getUserId());//委托人信息
        UserEntity fuser = fuserMapper.selectById(otcOrder.getUserId());
        UserEntity buyUser = null;
        UserEntity sellUser = null;


        if (otcEntrust.getType() == 0) {
            buyUser = entrustUser;
            sellUser = fuser;

        } else {
            buyUser = fuser;
            sellUser = entrustUser;
        }

        Map<UserEntity, String> msgUserMap = new HashMap<>();

        //买家已支付
        if (OtcOperEnum.PAYED == type) {
            //判断是否买家,并且给卖家

            if (!userId.equals(buyUser.getId())) {
                return new JsonResultVo(false, "订单用户不正确", -3);
            }
//            FuserPayAccount fuserPayAccount = fuserPayAccountService.selectByUserId(sellUser.getfId());
//            //payMethod 支付方式 1支付宝 2微信 3银行卡
//            if (fuserPayAccount == null) {
//                return new JsonResultVo(false, "未绑定支付方式", -3);
//            }

//            if (payMethod == 1) {
//                if (StringUtils.isBlank(fuserPayAccount.getfAlipayName())) {
//                    return new JsonResultVo(false, "该支付方式不存在", -3);
//                }
//            } else if (payMethod == 2) {
//                if (StringUtils.isBlank(fuserPayAccount.getfWenxinCode())) {
//                    return new JsonResultVo(false, "该支付方式不存在", -3);
//                }
//            } else {
//                if (StringUtils.isBlank(fuserPayAccount.getfBankNo())) {
//                    return new JsonResultVo(false, "该支付方式不存在", -3);
//                }
//            }

            if (sellUser.getValidateStatus() == 0) {
                return new JsonResultVo(false, "用户未身份证认证", -3);
            }
            if (otcOrder.getStatus() != 0) {
                return new JsonResultVo(false, "订单状态已改变", -3);
            }
            updateOrder.setPayMethod(payMethod);
            updateOrder.setPayDate(nowDate);
            result = otcOrderMapper.updateOrderPay(updateOrder);
            if (result < 0) {
                throw new ZeroResultException(new JsonResultVo(false, "订单状态已改变", -3));
            }

//            content = (String) redisService.getConfig("seller_already_paid");
//            msgUserMap.put(sellUser, content);
        } else if (OtcOperEnum.COMFIRM_MONEY == type) {
            //卖家确认收款
            if ((!userId.equals(sellUser.getId())) && (!isService)) {
                return new JsonResultVo(false, "订单用户不正确", -3);
            }


            if (otcOrder.getStatus() != OtcOperEnum.PAYED && otcOrder.getStatus() != OtcOperEnum.SELLER_COMPLAINT) {
                return new JsonResultVo(false, "订单状态已改变", -3);
            }
            if (sellUser.getMoneyPassword() == null && (!isService)) {
                return new JsonResultVo(false, "请先设置交易密码", null, 6004);
            }
            updateOrder.setCollectPayDate(nowDate);
            result = otcOrderMapper.updateOrderConfirmMoney(updateOrder);
            if (result < 0) {
                throw new ZeroResultException(new JsonResultVo(true, "订单状态已改变", -3));
            }


            //卖家放币
            BigDecimal finishFees = BigDecimal.ZERO;
            BigDecimal sellFees = BigDecimal.ZERO;
            BigDecimal sellActualCount = BigDecimal.ZERO;
            sellFees = otcOrder.getFees();
            if (otcEntrust.getType() == 1) {
//                BigDecimal div = MathUtil.div(otcOrder.getCountNum(), otcEntrust.getSeveral());
//                finishFees = MathUtil.getBigDecimal(mul(otcEntrust.getFees(), div), 8);
                finishFees = mul(otcOrder.getCountNum(), MathUtil.div(otcEntrust.getRate(), new BigDecimal("100")));
                sellFees = finishFees;
            }
            sellActualCount = otcOrder.getCountNum();

            WalletOper oper = new WalletOper();
//            oper.setTurnUserId(otcEntrust.getCoinId());
            oper.setUserId(sellUser.getId());
            oper.setAmount(MathUtil.add(otcOrder.getCountNum(), finishFees));
            oper.setOper(WalletOperEnum.REDUCE_FROZEN);
            JsonResultVo result1 = otcWalletService.updateWallet(oper);
            if (result1.getCode() <= 0) {
                throw new ZeroResultException(new JsonResultVo(RespInfo.NOT_ENOUGH_AMOUT.getMsg()));
            }

            BigDecimal countNum = BigDecimal.ZERO;

            //买家收币
            BigDecimal buyFees = BigDecimal.ZERO;
            BigDecimal buyCount = BigDecimal.ZERO;
            BigDecimal buyActualCount = BigDecimal.ZERO;
            countNum = MathUtil.getBigDecimal(MathUtil.sub(otcOrder.getCountNum(), otcOrder.getFees()), 8);
            buyFees = otcOrder.getFees();
            buyActualCount = otcOrder.getCountNum();
            if (otcEntrust.getType() == 0) {
                buyCount = countNum;
                BigDecimal countRate = mul(countNum, MathUtil.div(otcEntrust.getRate(), new BigDecimal("100")));
                buyFees = countRate;
                countNum = MathUtil.getBigDecimal(MathUtil.sub(countNum, countRate), 8);
                buyActualCount = buyCount;
            }

            oper = new WalletOper();
//            oper.setTurnUserId(otcEntrust.getCoinId());
            oper.setUserId(buyUser.getId());
            oper.setAmount(countNum);
            oper.setOper(WalletOperEnum.ADD);
            result1 = otcWalletService.updateWallet(oper);
            if (result1.getCode() <= 0) {
                throw new ZeroResultException(new JsonResultVo(RespInfo.NOT_ENOUGH_AMOUT.getMsg()));
            }
//            JsonResultVo jsonResultVo = otcOrderCountService.saveUserOtcOrderCount(otcEntrust.getUserId(), otcOrder.getUserId(), 2);
//            if (!jsonResultVo.isSuccess()) {
//                throw new ZeroResultException(RespInfo.FAILURE);
//            }

            //买入完成添加完成数量
//            if (otcOrder.getType() == 0) {
//                jsonResultVo = otcEntrustService.updateFinishCount(otcEntrust.getId(), otcOrder.getCountNum(), otcOrder.getPrize());
//            } else {
//                countNum = MathUtil.getBigDecimal(MathUtil.sub(otcOrder.getCountNum(), otcOrder.getFees()), 8);
//                jsonResultVo = otcEntrustService.updateFinishCount(otcEntrust.getId(), countNum, otcOrder.getPrize());
//            }
//            if (!jsonResultVo.isSuccess()) {
//                throw new ZeroResultException(RespInfo.FAILURE);
//            }

//            String isbird = fsystemargsMapper.findByFkey("isbird").getfValue();
//            String birdDate = fsystemargsMapper.findByFkey("birdDate").getfValue();
//            String noBirdDate = fsystemargsMapper.findByFkey("noBirdDate").getfValue();
//            String miningQuota = fsystemargsMapper.findByFkey("miningQuota").getfValue();
            OtcCoin otcCoin = otcCoinService.selectById(otcEntrust.getCoinId());

//            BigDecimal sellMiningAmount = new BigDecimal(miningService.findSumMiningAmountByUserId(sellUser.getfId()).getData().toString());
//            BigDecimal buyMiningAmount = new BigDecimal(miningService.findSumMiningAmountByUserId(buyUser.getfId()).getData().toString());
            JsonResultVo jsonResultVo = otcDayAmountService.saveOtcDayAmount(sellUser.getId(), MathUtil.getBigDecimal(mul(sellActualCount, otcOrder.getPrize()), 2));
            if (!jsonResultVo.isSuccess()) {
                throw new ZeroResultException(new JsonResultVo(RespInfo.FAILURE.getMsg()));
            }
            jsonResultVo = otcDayAmountService.saveOtcDayAmount(buyUser.getId(), MathUtil.getBigDecimal(mul(buyActualCount, otcOrder.getPrize()), 2));
            if (!jsonResultVo.isSuccess()) {
                throw new ZeroResultException(new JsonResultVo(RespInfo.FAILURE.getMsg()));
            }

            BigDecimal sellSub = BigDecimal.ZERO;
            BigDecimal buySub = BigDecimal.ZERO;
            //全员开放
//            if ("1".equals(isbird) && System.currentTimeMillis() > DateUtil.parse(DateUtil.DEFAULT_DATE_TIME, noBirdDate).getTime()) {
//                if(true){
//                if (sellMiningAmount.compareTo(new BigDecimal(miningQuota)) == -1) {
//                    BigDecimal sellAdd = MathUtil.add(sellMiningAmount, mul(sellActualCount, otcOrder.getPrize()));
//
//                    if (sellAdd.compareTo(new BigDecimal(miningQuota)) == 1) {
////                        BigDecimal sellSub = MathUtil.sub(sellAdd, new BigDecimal(miningQuota));
//                        //还差多少
//                        sellSub = MathUtil.sub(new BigDecimal(miningQuota), sellMiningAmount);
//                        //还差多少个
//                        BigDecimal sellDiv = MathUtil.getBigDecimal(MathUtil.div(sellSub, otcOrder.getPrize()), 8);
//                        //每个的手续费
//                        BigDecimal sellFeesDiv = MathUtil.getBigDecimal(MathUtil.div(sellFees, sellActualCount), 8);
//                        sellFees = MathUtil.getBigDecimal(mul(sellDiv, sellFeesDiv), 8);
//                        sellActualCount = sellDiv;
//                    }
//
//                    Mining mining = new Mining();
//                    mining.setType(1);
//                    mining.setCreateTime(System.currentTimeMillis());
//                    mining.setUpdateTime(System.currentTimeMillis());
//                    mining.setEntrustId(otcOrder.getId().toString());
//                    mining.setUserId(sellUser.getfId());
//                    mining.setFees(sellFees);
//                    if (sellSub.compareTo(BigDecimal.ZERO) == 0) {
//                        mining.setAmount(MathUtil.getBigDecimal(mul(sellActualCount, otcOrder.getPrize()), 2));
//                    } else {
//                        mining.setAmount(sellSub);
//                    }
//                    mining.setCoinId(otcCoin.getCoinId());
//                    jsonResultVo = miningService.saveMining(mining, 0);
//                    if (!jsonResultVo.isSuccess()) {
//                        throw new ZeroResultException(RespInfo.FAILURE);
//                    }
//                }
//
//                if (buyMiningAmount.compareTo(new BigDecimal(miningQuota)) == -1) {
//                    BigDecimal buyAdd = MathUtil.add(buyMiningAmount, mul(buyActualCount, otcOrder.getPrize()));
//                    if (buyAdd.compareTo(new BigDecimal(miningQuota)) == 1) {
//                        //还差多少
//                        buySub = MathUtil.sub(new BigDecimal(miningQuota), buyMiningAmount);
//                        //还差多少个
//                        BigDecimal buyDiv = MathUtil.getBigDecimal(MathUtil.div(buySub, otcOrder.getPrize()), 8);
//                        //每个的手续费
//                        BigDecimal buyFeesDiv = MathUtil.getBigDecimal(MathUtil.div(buyFees, buyActualCount), 8);
//                        buyFees = MathUtil.getBigDecimal(mul(buyDiv, buyFeesDiv), 8);
//                        buyActualCount = buyDiv;
//                    }
//
//                    Mining mining = new Mining();
//                    mining.setType(1);
//                    mining.setCreateTime(System.currentTimeMillis());
//                    mining.setUpdateTime(System.currentTimeMillis());
//                    mining.setEntrustId(otcOrder.getId().toString());
//                    mining.setUserId(buyUser.getfId());
//                    if (buySub.compareTo(BigDecimal.ZERO) == 0) {
//                        mining.setAmount(MathUtil.getBigDecimal(mul(buyActualCount, otcOrder.getPrize()), 2));
//                    } else {
//                        mining.setAmount(buySub);
//                    }
//                    mining.setFees(buyFees);
//                    mining.setCoinId(otcCoin.getCoinId());
//                    jsonResultVo = miningService.saveMining(mining, 0);
//                    if (!jsonResultVo.isSuccess()) {
//                        throw new ZeroResultException(RespInfo.FAILURE);
//                    }
//                }


//            } else {
//                //部分开放
//                String[] strings = birdDate.split("#");
//                long startTime = DateUtil.parse(DateUtil.DEFAULT_DATE_TIME, strings[0]).getTime();
//                long endTime = DateUtil.parse(DateUtil.DEFAULT_DATE_TIME, strings[1]).getTime();
//                if (System.currentTimeMillis() > startTime && System.currentTimeMillis() < endTime) {
//                    BirdUser sellBirdUser = birdUserService.findBirdUserByUserId(sellUser.getfId());
//                    BirdUser buyBirdUser = birdUserService.findBirdUserByUserId(buyUser.getfId());
//
//                    if (sellBirdUser != null) {
//                        if (sellMiningAmount.compareTo(new BigDecimal(miningQuota)) == -1) {
//                            BigDecimal sellAdd = MathUtil.add(sellMiningAmount, mul(sellActualCount, otcOrder.getPrize()));
//                            if (sellAdd.compareTo(new BigDecimal(miningQuota)) == 1) {
//                                //还差多少
//                                sellSub = MathUtil.sub(new BigDecimal(miningQuota), sellMiningAmount);
//                                //还差多少个
//                                BigDecimal sellDiv = MathUtil.getBigDecimal(MathUtil.div(sellSub, otcOrder.getPrize()), 8);
//                                //每个的手续费
//                                BigDecimal sellFeesDiv = MathUtil.getBigDecimal(MathUtil.div(sellFees, sellActualCount), 8);
//                                sellFees = MathUtil.getBigDecimal(mul(sellDiv, sellFeesDiv), 8);
//                                sellActualCount = sellDiv;
//                            }
//                            Mining mining = new Mining();
//                            mining.setType(1);
//                            mining.setCreateTime(System.currentTimeMillis());
//                            mining.setUpdateTime(System.currentTimeMillis());
//                            mining.setEntrustId(otcOrder.getId().toString());
//                            mining.setUserId(sellBirdUser.getUserId());
//                            mining.setFees(sellFees);
//                            if (sellSub.compareTo(BigDecimal.ZERO) == 0) {
//                                mining.setAmount(MathUtil.getBigDecimal(mul(sellActualCount, otcOrder.getPrize()), 2));
//                            } else {
//                                mining.setAmount(sellSub);
//                            }
//                            mining.setCoinId(otcCoin.getCoinId());
//                            jsonResultVo = miningService.saveMining(mining, 0);
//                            if (!jsonResultVo.isSuccess()) {
//                                throw new ZeroResultException(RespInfo.FAILURE);
//                            }
//                        }
//                    }
//
//                    if (buyBirdUser != null) {
//                        if (buyMiningAmount.compareTo(new BigDecimal(miningQuota)) == -1) {
//                            BigDecimal buyAdd = MathUtil.add(buyMiningAmount, mul(buyActualCount, otcOrder.getPrize()));
//                            if (buyAdd.compareTo(new BigDecimal(miningQuota)) == 1) {
//                                //还差多少
//                                buySub = MathUtil.sub(new BigDecimal(miningQuota), buyMiningAmount);
//                                //还差多少个
//                                BigDecimal buyDiv = MathUtil.getBigDecimal(MathUtil.div(buySub, otcOrder.getPrize()), 8);
//                                //每个的手续费
//                                BigDecimal buyFeesDiv = MathUtil.getBigDecimal(MathUtil.div(buyFees, buyActualCount), 8);
//                                buyFees = MathUtil.getBigDecimal(mul(buyDiv, buyFeesDiv), 8);
//                                buyActualCount = buyDiv;
//                            }
//
//                            Mining mining = new Mining();
//                            mining.setType(1);
//                            mining.setCreateTime(System.currentTimeMillis());
//                            mining.setUpdateTime(System.currentTimeMillis());
//                            mining.setEntrustId(otcOrder.getId().toString());
//                            mining.setUserId(buyBirdUser.getUserId());
//                            if (buySub.compareTo(BigDecimal.ZERO) == 0) {
//                                mining.setAmount(MathUtil.getBigDecimal(mul(buyActualCount, otcOrder.getPrize()), 2));
//                            } else {
//                                mining.setAmount(buySub);
//                            }
//                            mining.setFees(buyFees);
//                            mining.setCoinId(otcCoin.getCoinId());
//                            jsonResultVo = miningService.saveMining(mining, 0);
//                            if (!jsonResultVo.isSuccess()) {
//                                throw new ZeroResultException(RespInfo.FAILURE);
//                            }
//                        }
//                    }
//                }
//            }
            //完成时间
            updateOrder.setFinishDate(new Date());
            result = otcOrderMapper.updateOrderFinishDate(updateOrder);
            if (result < 0) {
                throw new ZeroResultException(new JsonResultVo(true, "订单状态已改变", -3));
            }

            if (otcEntrust.getSysAuto() == 1) {
                jsonResultVo = otcEntrustService.cancelAutoOtcEntrust(otcEntrust.getId(), otcEntrust.getUserId());
                if (!jsonResultVo.isSuccess()) {
                    throw new ZeroResultException(new JsonResultVo(RespInfo.FAILURE.getMsg()));
                }
            }


//            if (isService) {
//                content = (String) redisService.getConfig("seller_voucher_valid");
//                msgUserMap.put(sellUser, content);
//                content = (String) redisService.getConfig("buyer_voucher_valid");
//                msgUserMap.put(buyUser, content);
//            } else {
//                content = (String) redisService.getConfig("buyer_confirmation");
//                msgUserMap.put(buyUser, content);
//            }

        } else if (OtcOperEnum.BUYER_CANCEL == type || OtcOperEnum.TIMEOUT_CANCEL == type || OtcOperEnum.SERVICE_CANCEL == type) {
            //买家取消
            if (OtcOperEnum.BUYER_CANCEL == type && !userId.equals(buyUser.getId())) {
                return new JsonResultVo(false, "订单用户不正确", -3);
            }
            if (OtcOperEnum.BUYER_CANCEL == type) {
                if (otcOrder.getStatus() != OtcOperEnum.SELLER_COMPLAINT) {
                    return new JsonResultVo(false, "卖家未申诉，禁止取消", -3);
                }
            } else if (OtcOperEnum.SERVICE_CANCEL == type) {
                if (otcOrder.getStatus() != OtcOperEnum.SELLER_COMPLAINT) {
                    return new JsonResultVo(false, "订单状态已改变", -3);
                }
            } else {
                if (otcOrder.getStatus() != OtcOperEnum.INIT_STATUS) {
                    return new JsonResultVo(false, "订单状态已改变", -3);
                }
            }


            updateOrder.setCancelDate(nowDate);
            result = otcOrderMapper.updateCancelOrder(updateOrder);
            if (result < 0) {
                throw new ZeroResultException(new JsonResultVo(false, "订单状态已改变", -3));
            }
            //解冻委托单金额
            JsonResultVo jsonResultVo = null;
            if (otcOrder.getType() == 0) {
                jsonResultVo = otcEntrustService.updateSubDealCount(otcEntrust.getId(), otcOrder.getCountNum(), otcEntrust.getPrize());
            } else {
                jsonResultVo = otcEntrustService.updateSubDealCount(otcEntrust.getId(), MathUtil.sub(otcOrder.getCountNum(), otcOrder.getFees()), otcEntrust.getPrize());
            }
            if (!jsonResultVo.isSuccess()) {
                throw new ZeroResultException(new JsonResultVo(RespInfo.NOT_ENOUGH_AMOUT.getMsg()));
            }

            //取消申诉单
            if (otcEntrust.getStatus() == OtcOperEnum.SELLER_COMPLAINT) {
                OtcAppealVo otcAppealVo = new OtcAppealVo();
                otcAppealVo.setOrderId(otcOrder.getId());
                otcAppealVo.setOtcAppealOperEnum(OtcAppealOperEnum.SELLER_CANCEL);
                otcAppealVo.setUserId(userId);
                JsonResultVo vo = otcAppealService.updateOtcAppeal(otcAppealVo);
                if (!vo.isSuccess()) {
                    throw new ZeroResultException(new JsonResultVo(true, "订单处理异常", -3));
                }
            }
            int orderyType = otcEntrust.getType() == 0 ? 1 : 0;

            if (orderyType == 1) {
                WalletOper oper = new WalletOper();
//                oper.setTurnUserId(otcEntrust.getCoinId());
                oper.setUserId(otcOrder.getUserId());
                oper.setAmount(otcOrder.getCountNum());
                oper.setOper(WalletOperEnum.UNFRONZEN);
                oper.setRemark("取消订单解冻金额");
                JsonResultVo result1 = otcWalletService.updateWallet(oper);
                if (result1.getCode() <= 0) {
                    throw new ZeroResultException(new JsonResultVo(false, "下单失败：数据库异常", -1));
                }
            }
            //添加取消单数
//            JsonResultVo vo = otcOrderCountService.updateUserOtcOrderSysNum(buyUser.getfId());
//            if (!vo.isSuccess()) {
//                throw new ZeroResultException(new JsonResultVo(true, "订单处理异常", -3));
//            }
//            if (OtcOperEnum.TIMEOUT_CANCEL != type) {
//                vo = otcOrderCountService.updateUserOtcOrderSysNum(sellUser.getfId());
//                if (!vo.isSuccess()) {
//                    throw new ZeroResultException(new JsonResultVo(true, "订单处理异常", -3));
//                }
//            }


//            if (OtcOperEnum.BUYER_CANCEL == type) {
//                content = (String) redisService.getConfig("seller_cancel_order");
//                msgUserMap.put(sellUser, content);
//            } else if (OtcOperEnum.TIMEOUT_CANCEL == type) {
//                content = (String) redisService.getConfig("seller_cancel_order_out_time");
//                msgUserMap.put(sellUser, content);
//                content = (String) redisService.getConfig("buyer_cancel_order_out_time");
//                msgUserMap.put(buyUser, content);
//            } else if (OtcOperEnum.SERVICE_CANCEL == type) {
//                content = (String) redisService.getConfig("seller_voucher_invalid");
//                msgUserMap.put(sellUser, content);
//                content = (String) redisService.getConfig("buyer_voucher_invalid");
//                msgUserMap.put(buyUser, content);
//            }


        } else if (OtcOperEnum.SELLER_COMPLAINT == type) {
            //卖家申诉
            if (!userId.equals(sellUser.getId())) {
                return new JsonResultVo(false, "订单用户不正确", -3);
            }

            if (otcOrder.getStatus() != OtcOperEnum.PAYED) {
                return new JsonResultVo(false, "订单状态已改变", -3);
            }

            updateOrder.setModifyDate(nowDate);

            result = otcOrderMapper.updateSellerComplaintOrder(updateOrder);
            if (result < 0) {
                throw new ZeroResultException(new JsonResultVo(true, "订单状态已改变", -3));
            }

            //插入申诉记录
            OtcAppeal otcAppeal = new OtcAppeal();
            otcAppeal.setCreateTime(nowDate);
            otcAppeal.setOrderId(otcOrder.getId());
            otcAppeal.setApplyServersDate(nowDate);
            otcAppeal.setUpVoucherStatus(1);
            otcAppeal.setServersStatus(1);
            otcAppeal.setArbitrationStatus(0);
            result = otcAppealMapper.insert(otcAppeal);
            if (result < 0) {
                throw new ZeroResultException(new JsonResultVo(true, "数据异常，请重新申请", -3));
            }
//            content = (String) redisService.getConfig("buyer_appeal");
//            msgUserMap.put(buyUser, content);
        }


        //发送验证码

        OtcCoin otcCoin = otcCoinMapper.selectById(otcEntrust.getCoinId());//货币信息
        Set<UserEntity> keyUser = msgUserMap.keySet();
        if (otcOrder.getType() == 1) {
            otcOrder.setCountNum(MathUtil.sub(otcOrder.getCountNum(), otcOrder.getFees()));
            otcOrder.setAmount(mul(otcOrder.getCountNum(), otcOrder.getPrize()));
        }
//        for (UserEntity f : keyUser) {
//            content = msgUserMap.get(f);
//            content = content.replace("{coin_type}", otcCoin.getCoinName())
//                    .replace("{trading_time}", Utils.dateFormat(new Timestamp((new Date()).getTime())))
//                    .replace("{price}", MathUtil.getBigDecimalString(otcOrder.getPrize(), 2))
//                    .replace("{total_price}", MathUtil.getBigDecimalString(otcOrder.getAmount(), 2))
//                    .replace("{num}", MathUtil.getBigDecimalString(otcOrder.getCountNum(), 4))
//                    .replace("{order_number}", otcOrder.getOrderNumber())
//                    .replace("{contact_time}", redisService.getConfig("contact_time").toString());//真正的短信内容
//            boolean flag = userSupport.SendOtcMessage(f, content, 0); //发送短信通知
//            if (!flag) {
//                new ZeroResultException(new JsonResultVo(false, "服务异常", -3));
//            }
//        }

        return new JsonResultVo(true, "操作成功", 0);


//        mssageMap.put(-1,"seller_view_voucher&&buyer_upload_voucher");//对方已上传支付凭证，查看支付凭证


    }

    @Override
    @Transactional
    public JsonResultVo addOrder(Integer id, BigDecimal num, Integer userId) {


        OtcEntrust otcEntrust = otcEntrustMapper.selectById(id);
        if (otcEntrust == null) { //不存在委托信息
            return new JsonResultVo(false, "下单失败：不存在委托信息", -2);
        }
        if (otcEntrust.getUserId().equals(userId)) { //不存在委托信息
            return new JsonResultVo(false, "下单失败：不能购买自己发布的委托单", -2);
        }

        UserEntity fuser = fuserMapper.selectById(userId);
        //	判断当前是否已实名（即通过KYC1级）
        if (fuser.getValidateStatus() ==0) {
            return new JsonResultVo(false, "没有通过身份证认证", null, 6001);
        }

        //	判断是否预留手机号，若没有即跳转至预留页面
        if (fuser.getMobile() == null && fuser.getTelValidate() != 1) {
            return new JsonResultVo(false, "没有绑定手机号", 6002);
        }



//        OtcBlacklist otcBlacklistBlacklistByUserId = otcBlacklistService.selectOtcBlacklistByBlacklistUserId(userId, otcEntrust.getUserId());

//        if (otcBlacklistBlacklistByUserId != null) {
//            return new JsonResultVo(false, "您已被对方拉入黑名单，对方拒绝与您交易", null, -1);
//        }

//        OtcBlacklist otcBlacklistByUserId = otcBlacklistService.selectOtcBlacklistByUserId(userId, otcEntrust.getUserId());

//        if (otcBlacklistByUserId != null) {
//            return new JsonResultVo(false, "对方已被您拉入黑名单", null, -1);
//        }



//        FuserPayAccount fuserPayAccount = fuserPayAccountService.selectByUserId(userId);

//        if (fuserPayAccount == null) {
//            return new JsonResultVo(false, "请绑定支付方式", null, 6003);
//        }

        //	判断是否绑定银行卡或第三方支付方式
//        if (!Utils.hasLength(fuserPayAccount.getfAlipay()) && !Utils.hasLength(fuserPayAccount.getfWenxin()) && !Utils.hasLength(fuserPayAccount.getfBankNo())) {
//            return new JsonResultVo(false, "请绑定支付方式", null, 6003);
//        }
        if (otcEntrust.getStatus() != 1) {
            return new JsonResultVo(false, "下单失败：该委托单已卖完或暂停", -2);
        }

        Integer count = baseMapper.queryTodayCancelOrder(userId);
        if (count >= 3) {
            return new JsonResultVo(false, "您当前因取消订单超过三次，冻结当天下单权限", -2);
        }

        if (num.compareTo(MathUtil.getBigDecimal(num, 4)) != 0) {
            return new JsonResultVo(false, "数量格式不正确", -2);
        }

        OtcOrder queryOtcOrder = new OtcOrder();
        queryOtcOrder.setUserId(userId);
        queryOtcOrder.setType(otcEntrust.getType() == 0 ? 1 : 0);
        queryOtcOrder.setCoinId(otcEntrust.getCoinId());

//        count = baseMapper.queryNowBuyingOrder(queryOtcOrder);
//        if(count>=1) {
//        	return new JsonResultVo(false, "当前有未完成订单", -2);
//        }
        BigDecimal money = BigDecimal.ZERO;
        otcEntrustService.autoIndexTickerPrice(otcEntrust.getCoinId(), otcEntrust);
        BigDecimal prize = otcEntrust.getPrize();
        money = MathUtil.getBigDecimal(mul(prize, num), 2);


        BigDecimal limitMinAmount = new BigDecimal(otcEntrust.getLimitAmount().split("-")[0]);
        BigDecimal maxAmount = new BigDecimal(otcEntrust.getLimitAmount().split("-")[1]);
        BigDecimal dealAmount = mul(otcEntrust.getPrize(), otcEntrust.getDealCount());
        BigDecimal amount = mul(otcEntrust.getPrize(), otcEntrust.getSeveral());
        BigDecimal remainAmount = MathUtil.getBigDecimal(MathUtil.sub(amount, dealAmount), 2);
        if (money.compareTo(remainAmount) > 0) {
            return new JsonResultVo(false, "当前金额大于委托单总额，请重新下单", -5);
        }

        DecimalFormat df = new DecimalFormat("#,###");
        if (money.compareTo(limitMinAmount) == -1) { //购买总金额小于最小限额
            return new JsonResultVo(false, "对方设置的单笔限额为" + df.format(limitMinAmount) + "-" + df.format(maxAmount), -3);
        }

        if (money.compareTo(maxAmount) == 1) {
            return new JsonResultVo(false, "对方设置的单笔限额为" + df.format(limitMinAmount) + "-" + df.format(maxAmount), -4);
        }

        String quota = fsystemargsService.getValue("quota");
        String[] quotas = quota.split("-");

        //	判断当前是否已实名（即通过KYC1级）
        if (fuser.getValidateStatus() ==0) {
            return new JsonResultVo(false, "没有身份证认证，前去认证", null, -1);
        }

        int type = otcEntrust.getType() == 0 ? 1 : 0;
        if (type == 1) {

            WalletEntity otcWallet = otcWalletService.selectByUserId(userId);
            if (otcWallet.getTotal().compareTo(num) < 0) {
                return new JsonResultVo(false, "账户可用数量不够", -6);
            }
        }

        UserEntity wef_user = fuserMapper.selectById(otcEntrust.getUserId());
        OtcCoin otcCoin = otcCoinMapper.selectById(otcEntrust.getCoinId());


        //符合条件
        Date nowDate = new Date();
        OtcOrder otcOrder = new OtcOrder();
        otcOrder.setEntrustId(id);
        otcOrder.setUserId(userId);
        otcOrder.setType(type);
        otcOrder.setCreateDate(nowDate);
        otcOrder.setModifyDate(nowDate);
        otcOrder.setStatus(0);
        otcOrder.setPrize(prize);
        otcOrder.setAmount(money);
        otcOrder.setCountNum(num);
        otcOrder.setOrderNumber(OrderUtils.getOrderIdByUUId());

        OtcFeeConfig configByUserId = otcFeeConfigService.findOtcFeeConfigByUserId(userId);
        if(configByUserId!=null){
            otcOrder.setRate(MathUtil.mul(configByUserId.getOrderFee(),new BigDecimal("100")));
            otcOrder.setFees(mul(num,configByUserId.getOrderFee()));
        }else {
            otcOrder.setRate(otcCoin.getRate());
            otcOrder.setFees(mul(num, MathUtil.div(otcCoin.getRate(), new BigDecimal("100"))));
        }


        BigDecimal dealFees = BigDecimal.ZERO;
        if (otcEntrust.getType() == 0) {
            dealFees = MathUtil.getBigDecimal(mul(MathUtil.sub(num, otcOrder.getFees()), MathUtil.div(otcEntrust.getRate(), new BigDecimal("100"))), 8);
        } else {
//            BigDecimal div = MathUtil.div(num, otcEntrust.getSeveral());
//            dealFees = MathUtil.getBigDecimal(mul(otcEntrust.getFees(), div), 8);
            dealFees=MathUtil.getBigDecimal(mul(num, MathUtil.div(otcEntrust.getRate(), new BigDecimal("100"))), 8);
        }
        otcOrder.setEntrustFees(dealFees);

        int result = otcOrderMapper.insert(otcOrder);
        if (result <= 0) {
            throw new ZeroResultException(new JsonResultVo(false, "下单失败：数据库异常", -1));
        }

        if (type == 1) {
            WalletOper oper = new WalletOper();
//            oper.setTurnUserId(otcEntrust.getCoinId());
            oper.setUserId(userId);
            oper.setAmount(num);
            oper.setOper(WalletOperEnum.FROZEN);
            oper.setRemark("下卖单冻结金额");
            JsonResultVo result1 = otcWalletService.updateWallet(oper);
            if (result1.getCode() <= 0) {
                throw new ZeroResultException(new JsonResultVo(false, "下单失败：数据库异常", -1));
            }
        }

//        OtcEntrust updateOtcEntrust = new OtcEntrust();
//        updateOtcEntrust.setId(otcEntrust.getId());
//        updateOtcEntrust.setDealAmount(money);
//        updateOtcEntrust.setDealCount(num);
//        updateOtcEntrust.setModifyDate(nowDate);
        //更新委托信息--成交额和成交数量
        //冻结成交额和成交数量
        JsonResultVo resultVo = null;
        if (type == 0) {
            resultVo = otcEntrustService.updateAddDealCount(otcEntrust.getId(), num, prize);
        } else {
            resultVo = otcEntrustService.updateAddDealCount(otcEntrust.getId(), MathUtil.sub(num, otcOrder.getFees()), prize);
        }

        if (!resultVo.isSuccess()) {
            throw new ZeroResultException(new JsonResultVo(false, "下单失败：余额不足", -7));
        }

//        JsonResultVo jsonResultVo = otcOrderCountService.saveUserOtcOrderCount(otcEntrust.getUserId(), userId, 1);
//        if (!jsonResultVo.isSuccess()) {
//            throw new ZeroResultException(new JsonResultVo(false, "数据异常", -7));
//        }

        //委托成功发送短信
        String content = "";
        Map<String, Object> parms = new HashMap<>();
        if (otcEntrust.getType() == 0) {//买入的委托单->买家
            parms.put("fKey", "buyer_generating_order");
            content = fsystemargsMapper.selectByMap(parms).get(0).toString();
        } else {
            parms.put("fKey", "seller_wait_pay");
            content = fsystemargsMapper.selectByMap(parms).get(0).toString();
        }

        if (type == 1) {
            num = MathUtil.sub(num, otcOrder.getFees());
            money = MathUtil.getBigDecimal(mul(prize, num), 2);
        }

//        content = content.replace("{coin_type}", otcCoin.getCoinName())
//                .replace("{trading_time}", Utils.dateFormat(new Timestamp(otcOrder.getCreateDate().getTime())))
//                .replace("{price}", MathUtil.getBigDecimalString(prize, 2))
//                .replace("{total_price}", MathUtil.getBigDecimalString(money, 2))
//                .replace("{order_number}", otcOrder.getOrderNumber() + "")
//                .replace("{num}", MathUtil.getBigDecimalString(num, 4));//真正的短信内容
//        boolean flag = userSupport.SendOtcMessage(wef_user, content, 0); //发送短信通知-给委托方
//        if (!flag) {
//            throw new ZeroResultException(new JsonResultVo(false, "下单失败：数据库异常", -1));
//        }
        return new JsonResultVo(true, "下单成功",otcOrder,0);


    }


    /**
     * 获取订单信息列表
     *
     * @param map
     * @return
     */
    @Override
    public List<Map<String, Object>> getOrderInfoByMap(Map<String, Object> map) {
        return otcOrderMapper.getOrderInfoByMap(map);
    }


    @Override
    public Page<Map<String, Object>> selectOtcOrderMapPage(OtcOrder queryOtcOrder, Page<Map<String, Object>> page) {
        List<Map<String, Object>> list = otcOrderMapper.selectOtcOrderMapPage(queryOtcOrder, page);
        page.setRecords(list);
        return page;
    }


    @Override
    public Map<String, Object> getOrderContact(Integer id, Integer userId) {
        Map<String, Object> map = otcOrderMapper.getOrderContact(id);
        Map<String, Object> returnMap = new HashMap<String, Object>();
        if (userId.equals(map.get("userId")) || userId.equals(map.get("entrustUserId"))) {
            if (Integer.parseInt(map.get("type").toString()) == 0) {
                returnMap.put("sellerPhone", map.get("orderfTelephone"));
                returnMap.put("buyerPhone", map.get("entrustfTelephone"));
            } else {
                returnMap.put("buyerPhone", map.get("orderfTelephone"));
                returnMap.put("sellerPhone", map.get("entrustfTelephone"));
            }


        }

        return returnMap;
    }


    @Override
    public List<OtcOrder> queryTimeoutNoPayList() {

        return baseMapper.queryTimeoutNoPayList();
    }


    @Override
    public List<OtcOrder> queryAppealTimeoutNoUploadList() {
        return baseMapper.queryAppealTimeoutNoUploadList();
    }


    @Override
    public List<OtcOrder> queryCofirmTimeoutList() {
        return baseMapper.queryCofirmTimeoutList();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePayNoStatus() {
//        String content = redisService.getConfig("sell_no_currency").toString();
        List<Map<String,Object>> otcOrderList=  baseMapper.queryPayNoStatusList();
        for (Map<String,Object> otcOrder : otcOrderList) {
            BigDecimal num = new BigDecimal(otcOrder.get("countNum").toString());
            BigDecimal money= new BigDecimal(otcOrder.get("amount").toString());
            BigDecimal fees= new BigDecimal(otcOrder.get("fees").toString());
            BigDecimal prize= new BigDecimal(otcOrder.get("prize").toString());
            Integer userId= Integer.valueOf(otcOrder.get("userId").toString());
            Integer eUserId= Integer.valueOf(otcOrder.get("eUserId").toString());
            Integer id= Integer.valueOf(otcOrder.get("id").toString());
            UserEntity fuser= null;
            if ("1".equals(otcOrder.get("type").toString())) {
                num = MathUtil.sub(num, fees);
                money = MathUtil.getBigDecimal(mul(prize, num), 2);
                fuser=fuserMapper.selectById(userId);
            }else {
                fuser=fuserMapper.selectById(eUserId);
            }

            Integer  result= baseMapper.updatePayNoStatusMsg(id);

            if (result <= 0) {
                throw new ZeroResultException(new JsonResultVo(false, "支付未操作短信执行失败：数据库异常1", -1));
            }

//            content = content.replace("{coin_type}", otcOrder.get("coinName").toString())
//                    .replace("{price}", MathUtil.getBigDecimalString(prize, 2))
//                    .replace("{total_price}", MathUtil.getBigDecimalString(money, 2))
//                    .replace("{order_number}", otcOrder.get("orderNumber").toString())
//                    .replace("{num}", MathUtil.getBigDecimalString(num, 4));

//            boolean flag = userSupport.SendOtcMessage(fuser, content, 0);
//            if (!flag) {
//                throw new ZeroResultException(new JsonResultVo(false, "支付未操作短信执行失败：数据库异常2", -1));
//            }
        }
    }

    @Override
    public List<OtcOrder> getFees(long startDate, long endDate) {
        return baseMapper.getFees(new Date(startDate), new Date(endDate));
    }

    @Override
    public Map<String, Object> selectOtcOrderMapById(Integer id, Integer userId) {
        return otcOrderMapper.selectOtcOrderMapById(id, userId);
    }

    @Override
    public int queryNowOrder(Integer type, Integer userId) {
        OtcOrder otcOrder = new OtcOrder();
        otcOrder.setType(type);
        otcOrder.setUserId(userId);
        return otcOrderMapper.queryNowOrder(otcOrder);
    }

    @Override
    public int queryNowOwnOrder(Integer type, Integer userId) {
        OtcOrder otcOrder = new OtcOrder();
        otcOrder.setType(type);
        otcOrder.setUserId(userId);
        return otcOrderMapper.queryNowOwnOrder(otcOrder);
    }
}
